<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>俄罗斯方块游戏</title>
    <style>
        table {
            margin-left: 30px;
            border-collapse: collapse;
            background-color: rgb(30, 30, 30);
        }

        td {
            width: 30px;
            height: 30px;
            border: 1px solid rgb(100, 100, 100);
        }

        .color1 {
            background-image:-webkit-linear-gradient(top left, red,rgb(255, 234, 234));
        }

        .color2 {
            background-image:-webkit-linear-gradient(top left, rgb(255, 109, 0),rgb(255, 255, 255)) ;
        }

        .color3 {
            background-image:-webkit-linear-gradient(top left, yellow,rgb(255, 255, 255)) ;
        }

        .color4 {
            background-image:-webkit-linear-gradient(top left, green,rgb(255, 255, 255)) ;
        }

        .color5 {
            background-image:-webkit-linear-gradient(top left, rgb(9, 255, 34),rgb(255, 255, 255)) ;
        }

        .color6 {
            background-image:-webkit-linear-gradient(top left,  blue,rgb(255, 255, 255));
        }

        .color7 {
            background-image:-webkit-linear-gradient(top left, purple,rgb(255, 255, 255)) ;
        }
    </style>
</head>

<body>
    <h1>当前分数：</h1>
    <table id="table">

    </table>
    <!-- 请在这里进行开发 -->
    <!-- 嘿嘿，今天先创建分支，俺明天再卷 -->
    <script>
        // 一、先写一个大表格和分数
        var Score = document.querySelector('h1');
        var table = document.getElementById('table');
        for (var i = 1; i <= 20; i++) {
            var tr = document.createElement('tr')
            for (var j = 1; j <= 12; j++) {
                var td = document.createElement('td');
                tr.appendChild(td);
                // 孤儿上数，也可以写成==
                // tr.insertBefore(td, tr.firsttd)
            }
            table.appendChild(tr);
            // 孤儿上数，也可以写成==
            // table.insertBefore(tr, table.firsttr)
        }
        // 二、写一个染色函数
        function render(h, l, n) {
            table.getElementsByTagName('tr')[h].getElementsByTagName('td')[l].className = 'color' + n;
        }
        // 浅浅试了一下可以哦，嘿嘿
        // render(1,1,1);
        // render(2,2,2);
        // render(3,3,3);
        // render(4,4,4);
        // render(5,5,5);
        // render(7,7,7);
        // render(6,6,6);

        // 定义一个全局变量，定分
        var score = 0;
        // 三、书写一个带颜色，可以变化的砖块
        var brick = [
            [0, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0],
        ];
        candomInBrick()
        
        var brickTr = 0;
        var brickTd = 4;

        var map = [
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [7, 7, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0],
            [7, 1, 1, 2, 0, 0, 3, 6, 0, 0, 0, 5],
            [1, 1, 2, 2, 0, 0, 3, 6, 6, 6, 5, 5],
            [2, 2, 2, 2, 2, 0, 3, 4, 4, 4, 4, 5],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
            // stop,停下来，给他砌堵墙
        ];
        function draw_brick() {
            for (var i = 0; i < 4; i++) {
                for (var j = 0; j < 4; j++) {
                    if (brick[i][j] != 0) {
                        render(brickTr + i, brickTd + j, brick[i][j]);
                    }
                }
            }
        }
        draw_brick()
        // 四、先设置死区地图
        function draw_map() {
            for (var i = 0; i < 20; i++) {
                for (var j = 0; j < 12; j++) {
                    if (map[i][j] != 0) {
                        render(i, j, map[i][j])
                    }
                }
            }
        }
        draw_map();
        // 五、设置定时器，砖块下落
        // emmm,全部掉不下来，先清屏，把清屏，死区地图，砖块下落最后再放在一起
        // 六、挂住，停住（包含循环落下，上一个下落就成为那个死区地图）
        function clear() {
            for (var i = 0; i < 20; i++) {
                for (var j = 0; j < 12; j++) {
                    table.getElementsByTagName('tr')[i].getElementsByTagName('td')[j].className = '';
                }
            }
        }
        function canFall() {
            for (var i = 0; i < 4; i++) {
                for (var j = 0; j < 4; j++) {
                    if (brick[i][j] != 0 && map[brickTr + i + 1][brickTd + j] != 0) {
                        return false;
                    }
                }
            }
            return true
        }

        function candomInBrick() {
            var brick_all = [
                [
                    [0, 0, 0, 0],
                    [0, 1, 1, 0],
                    [1, 1, 0, 0],
                    [0, 0, 0, 0],
                ],
                [
                    [0, 0, 0, 0],
                    [0, 2, 0, 0],
                    [0, 2, 0, 0],
                    [0, 2, 2, 0],
                ],
                [
                    [0, 3, 0, 0],
                    [0, 3, 0, 0],
                    [0, 3, 0, 0],
                    [0, 3, 0, 0],
                ],
                [
                    [0, 0, 0, 0],
                    [0, 4, 4, 0],
                    [0, 4, 4, 0],
                    [0, 0, 0, 0],
                ],
                [
                    [0, 0, 5, 0],
                    [0, 5, 5, 0],
                    [0, 0, 5, 0],
                    [0, 0, 0, 0],
                ],
                [
                    [0, 0, 0, 0],
                    [0, 6, 6, 0],
                    [0, 6, 0, 0],
                    [0, 6, 0, 0],
                ],
                [
                    [0, 0, 0, 0],
                    [7, 7, 0, 0],
                    [0, 7, 7, 0],
                    [0, 0, 0, 0],
                ]
            ];
            var a = parseInt(Math.random() * 7);
            brick = brick_all[a];
            brickTr = 0;
            brickTd = 4;
        }

        function canClearTr() {
            var count = 0;
            for (var i = 19; i >= 0; i--) {
                if (!map[i].includes(0)) {
                    map.splice(i, 1);
                    count++;
                }
            }
            // 写一个加分
            score += count;
            Score.innerText = '当前分数:' + score
            for (var i = 0; i < count; i++) {
                map.unshift([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
            }
        }
        // emmm,好像要先写函数，最后放进去，这样好看一点
        var timer = setInterval(function () {
            clear();
            if (canFall()) {
                brickTr++;
            } else {
                // ps:这里给加了下落以后堆小山，还是蛮方便的，就直接在计时器这里写，嘿嘿
                for (var i = 0; i < 4; i++) {
                    for (var j = 0; j < 4; j++) {
                        if (brick[i][j] != 0) {
                            map[brickTr + i][brickTd + j] = brick[i][j];
                        }
                    }
                }
                candomInBrick();
                canClearTr();
                if (!canFall()) {
                    alert('GAMEOVER,请刷新网络界面从新来过')
                    clearInterval(timer);
                }
            }
            draw_brick();
            draw_map();

        }, 100);


        // 七、给设置左右→，可以移动，嘿嘿嘿
        // 写一个判断能否左右移动的函数
        function canToL() {
            for (var i = 0; i < 4; i++) {
                for (var j = 0; j < 4; j++) {
                    if (brick[i][j] != 0 && map[brickTr + i][brickTd + j - 1] != 0) {
                        return false;
                    }
                }
            }
            return true;
        }
        function canToR() {
            for (var i = 0; i < 4; i++) {
                for (var j = 0; j < 4; j++) {
                    if (brick[i][j] != 0 && map[brickTr + i][brickTd + j + 1] != 0) {
                        return false;
                    }
                }
            }
            return true;
        }
        // 八、写随机产生新的方块的代码（有7种小方块，可以随便写，但是砖头数组，还是要从0,1,2,3,4,5,6这样从0开始

        function rotate() {
            var result = [
                [],
                [],
                [],
                []
            ];
            for (var i = 0; i < 4; i++) {
                for (var j = 3; j >= 0; j--) {
                    result[i].push(brick[j][i])
                }
            }
            return result;
        }

        function canRotate() {
            var Ls = rotate();
            for (var i = 0; i < 4; i++) {
                for (var j = 0; j < 4; j++) {
                    if (Ls[i][j] != 0 && map[brickTr + i][brickTd + j] != 0) {
                        return false;
                    }
                }
            }
            return true
        }
        // 监听37,38,39
        document.onkeydown = function (e) {
            if (e.keyCode == 37) {
                if (canToL()) {
                    brickTd--;
                    clear();
                    draw_brick();
                    draw_map();
                }
            } else if (e.keyCode == 39) {
                if (canToR()) {
                    brickTd++;
                    clear();
                    draw_brick();
                    draw_map();
                }
            } else if (e.keyCode == 38) {
                if (canRotate()) {
                    brick = rotate();
                    clear();
                    draw_map();
                    draw_brick();
                }
            } else if (e.keyCode == 32) {
                while (canFall()) {
                    brickTr++;
                }
            }
        };
    </script>
</body>

</html>